﻿using LCL.Network.Profinet.Siemens;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace LCL.NetworkDemo.PLC
{
    public partial class FormSiemens : Form
    {
        private SiemensS7Net siemensTcpNet = null;
        private SiemensPLCS siemensPLCSelected = SiemensPLCS.S1200;
        public FormSiemens(SiemensPLCS siemensPLCS)
        {
            InitializeComponent();
            siemensPLCSelected = siemensPLCS;
            siemensTcpNet = new SiemensS7Net(siemensPLCS);
        }
        private void FormSiemens_Load(object sender, EventArgs e)
        {
            #region Load
            this.txtMemory.SelectedIndex = 1;
            this.txtDataType.SelectedIndex = 1;
            this.textBox1.Text = Utils.GetIP();
            this.textBox2.Text = "8080";
            panel2.Enabled = false;
            userCurve1.SetLeftCurve("A", new float[0], Color.Tomato);

            if (!Program.ShowAuthorInfomation)
            {
                label2.Visible = false;
                linkLabel1.Visible = false;
            }

            if (siemensPLCSelected == SiemensPLCS.S400)
            {
                textBox15.Text = "0";
                textBox16.Text = "3";
            }
            else if (siemensPLCSelected == SiemensPLCS.S1200)
            {
                textBox15.Text = "0";
                textBox16.Text = "0";
            }
            else if (siemensPLCSelected == SiemensPLCS.S300)
            {
                textBox15.Text = "0";
                textBox16.Text = "2";
            }
            else if (siemensPLCSelected == SiemensPLCS.S1500)
            {
                textBox15.Text = "0";
                textBox16.Text = "0";
            }
            #endregion
        }
     
        #region 连接/断开连接
        private void butConnect_Click(object sender, EventArgs e)
        {
            System.Net.IPAddress address;
            // 连接
            if (!System.Net.IPAddress.TryParse(textBox1.Text, out address))
            {
                MessageBox.Show("Ip地址输入不正确！");
                return;
            }
            siemensTcpNet.IpAddress = this.textBox1.Text;
            siemensTcpNet.Port =Utils.GetObjTranNull<int>(this.textBox2.Text);
            try
            {
                if (siemensPLCSelected != SiemensPLCS.S200Smart)
                {
                    siemensTcpNet.Rack = byte.Parse(textBox15.Text);
                    siemensTcpNet.Slot = byte.Parse(textBox16.Text);
                }
                Result connect = siemensTcpNet.ConnectServer();
                if (connect.Success)
                {
                    MessageBox.Show("连接成功！");
                    butDisconnect.Enabled = true;
                    butConnect.Enabled = false;
                    panel2.Enabled = true;
                }
                else
                {
                    MessageBox.Show("连接失败！");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void butDisconnect_Click(object sender, EventArgs e)
        {
            // 断开连接
            siemensTcpNet.ConnectClose();
            butDisconnect.Enabled = false;
            butConnect.Enabled = true;
            panel2.Enabled = false;
        }
        #endregion

        #region 统一读取写入数据
         /// <summary>
        /// 统一的读取结果的数据解析，显示
        /// </summary>
        private void readResultRender<T>( Result<T> result, string address, TextBox textBox )
        {
            if (result.Success)
            {
                textBox.AppendText( DateTime.Now.ToString( "[HH:mm:ss] " )
                    + "[" + address + "] " + result.Data + "" + Environment.NewLine + "");
            }
            else
            {
                MessageBox.Show( DateTime.Now.ToString( "[HH:mm:ss] " )
                    + "[" + address + "] 读取失败" + Environment.NewLine + "原因：" + result.ToMessageShowString() + "");
            }
        }
         /// <summary>
        /// 统一的数据写入的结果显示
        /// </summary>
        private void writeResultRender(Result result, string address )
        {
            if (result.Success)
            {
                MessageBox.Show( DateTime.Now.ToString( "[HH:mm:ss] " ) + "[" + address + "] 写入成功" );
            }
            else
            {
                MessageBox.Show(DateTime.Now.ToString("[HH:mm:ss] ") 
                    + "[" + address + "] 写入失败" + Environment.NewLine + "原因：" + result.ToMessageShowString() + "");
            }
        }
        #endregion
        
        //单数据读取测试
        private void butRead_Click(object sender, EventArgs e)
        { //单数据读取测试
           string memory= this.txtMemory.Text.ToUpper().Trim();
           string address = this.txtAddress.Text.Trim();
           string length = this.txtLength.Text.Trim();
           string dataType= this.txtDataType.Text.ToLower().Trim();

           string add = memory + address;
           switch (dataType)
           {
               case"bool":
                   // 读取bool变量
                   readResultRender(siemensTcpNet.ReadBool(add), add, txtResult);
                   break;
               case "byte":
                     readResultRender(siemensTcpNet.ReadByte(add), add, txtResult);
                   break;
               case "short":
                   readResultRender(siemensTcpNet.ReadInt16(add), add, txtResult);
                   break;
               case "ushort":
                   readResultRender(siemensTcpNet.ReadUInt16(add), add, txtResult);
                   break;
               case "int":
                   readResultRender(siemensTcpNet.ReadInt32(add), add, txtResult);
                   break;
               case "uint":
                   readResultRender(siemensTcpNet.ReadUInt32(add), add, txtResult);
                   break;
               case "long":
                   readResultRender(siemensTcpNet.ReadInt64(add), add, txtResult);
                   break;
               case "ulong":
                   readResultRender(siemensTcpNet.ReadUInt64(add), add, txtResult);
                   break;
               case "float":
                   readResultRender(siemensTcpNet.ReadFloat(add), add, txtResult);
                   break;
               case "double":
                   readResultRender(siemensTcpNet.ReadDouble(add), add, txtResult);
                   break;
               case "string":
                   readResultRender(siemensTcpNet.ReadString(add, ushort.Parse(txtLength.Text)), add, txtResult);
                   break;
               default:
                   break;
           }
        }
        //单数据写入测试
        private void butWrite_Click(object sender, EventArgs e)
        {//单数据写入测试
            string memory = this.txtMemory.Text.ToUpper().Trim();
            string address = this.txtAddress.Text.Trim();
            string length = this.txtLength.Text.Trim();
            string dataType = this.txtDataType.Text.ToLower().Trim();
            string value = this.txtValue.Text.Trim();

            string add = memory + address;
            switch (dataType)
            {
                case "bool":
                    writeResultRender(siemensTcpNet.Write(add, bool.Parse(value)), add);
                    break;
                case "byte":
                    writeResultRender(siemensTcpNet.Write(add, byte.Parse(value)), add);
                    break;
                case "short":
                    writeResultRender(siemensTcpNet.Write(add, short.Parse(value)), add);
                    break;
                case "ushort":
                    writeResultRender(siemensTcpNet.Write(add, ushort.Parse(value)), add);
                    break;
                case "int":
                    writeResultRender(siemensTcpNet.Write(add, int.Parse(value)), add);
                    break;
                case "uint":
                    writeResultRender(siemensTcpNet.Write(add, uint.Parse(value)), add);
                    break;
                case "long":
                    writeResultRender(siemensTcpNet.Write(add, long.Parse(value)), add);
                    break;
                case "ulong":
                    writeResultRender(siemensTcpNet.Write(add, ulong.Parse(value)), add);
                    break;
                case "float":
                    writeResultRender(siemensTcpNet.Write(add, float.Parse(value)), add);
                    break;
                case "double":
                    writeResultRender(siemensTcpNet.Write(add, double.Parse(value)), add);
                    break;
                case "string":
                    writeResultRender(siemensTcpNet.Write(add, value), add);
                    break;
                default:
                    break;
            }
        }
        //订货号
        private void butReadOrderNumber_Click(object sender, EventArgs e)
        {
            // 订货号
            Result<string> read = siemensTcpNet.ReadOrderNumber();
            if (read.Success)
            {
                txtResult.Text = "订货号：" + read.Data;
            }
            else
            {
                MessageBox.Show("读取失败：" + read.ToMessageShowString());
            }
        }
        //批量读取
        private void butBatchRead_Click(object sender, EventArgs e)
        {
            try
            {
                string memory = this.txtMemory.Text.ToUpper().Trim();
                string address = this.txtAddress.Text.Trim();
                string length = this.txtLength.Text.Trim();
                string dataType = this.txtDataType.Text.ToLower().Trim();

                string add = memory + address;
                Result<byte[]> read = siemensTcpNet.Read(add, ushort.Parse(length));
                if (read.Success)
                {
                    // 此处需要根据实际的情况来自定义来处理复杂的数据
                    //short D100 = siemensTcpNet.ByteTransform.TransInt16(read.Data, 0);
                    //short D101 = siemensTcpNet.ByteTransform.TransInt16(read.Data, 2);
                    //short D102 = siemensTcpNet.ByteTransform.TransInt16(read.Data, 4);
                    //short D103 = siemensTcpNet.ByteTransform.TransInt16(read.Data, 6);
                    //short D104 = siemensTcpNet.ByteTransform.TransInt16(read.Data, 7);

                   this.txtResult.Text = "结果：" + Utils.ByteToHexString(read.Data);
                }
                else
                {
                    MessageBox.Show("读取失败：" + read.ToMessageShowString());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取失败：" + ex.Message);
            }
        }
        //报文读取
        private void butMessage_Click(object sender, EventArgs e)
        {
            try
            {
                Result<byte[]> read = siemensTcpNet.ReadFromCoreServer(Utils.HexStringToBytes(this.txtMessage.Text));
                if (read.Success)
                {
                    this.txtResult.Text = "结果：" + Utils.ByteToHexString(read.Data);
                }
                else
                {
                    MessageBox.Show("读取失败：" + read.ToMessageShowString());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取失败：" + ex.Message);
            }
        }
        //热启动
        private void butHotStart_Click(object sender, EventArgs e)
        {
            //热启动
            Result result = siemensTcpNet.HotStart();
            if (result.Success)
            {
                MessageBox.Show("Success");
            }
            else
            {
                MessageBox.Show("Failed: " + result.Message);
            }
        }
        //冷启动
        private void butColdStart_Click(object sender, EventArgs e)
        {
            // 冷启动
            Result result = siemensTcpNet.ColdStart();
            if (result.Success)
            {
                MessageBox.Show("Success");
            }
            else
            {
                MessageBox.Show("Failed: " + result.Message);
            }
        }
        //停止
        private void butStop_Click(object sender, EventArgs e)
        {
            // 停止
            Result result = siemensTcpNet.Stop();
            if (result.Success)
            {
                MessageBox.Show("Success");
            }
            else
            {
                MessageBox.Show("Failed: " + result.Message);
            }
        }
       
        #region  定时器读取测试
        private Thread thread = null;// 后台读取的线程
        private int timeSleep = 300; // 读取的间隔
        private bool isThreadRun = false; // 用来标记线程的运行状态
        //定时器读取测试
        private void butCurve_Click(object sender, EventArgs e)
        {
            // 启动后台线程，定时读取PLC中的数据，然后在曲线控件中显示
            if (!isThreadRun)
            {
                if (!int.TryParse(textBox14.Text, out timeSleep))
                {
                    MessageBox.Show("间隔时间格式输入错误！");
                    return;
                }
                butCurve.Text = "停止";
                isThreadRun = true;
                thread = new Thread(ThreadReadServer);
                thread.IsBackground = true;
                thread.Start();
            }
            else
            {
                butCurve.Text = "启动";
                isThreadRun = false;
            }
        }
        private void ThreadReadServer()
        {
            string add= this.textBox12.Text;
            while (isThreadRun)
            {
                Thread.Sleep(timeSleep);
                try
                {
                    Result<short> read = siemensTcpNet.ReadInt16(add);
                    if (read.Success)
                    {
                        // 显示曲线
                        if (isThreadRun) Invoke(new Action<short>(AddDataCurve), read.Data);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("读取失败：" + ex.Message);
                }

            }
        }
        private void AddDataCurve(short data)
        {
            userCurve1.AddCurveData("A", data);
        }
        #endregion

        private void FormSiemens_FormClosing(object sender, FormClosingEventArgs e)
        {
            isThreadRun = false;
        }

      

      
       
    }
}
